import asyncio
import json

from fastapi import APIRouter, Request, WebSocket
from qiniu import Auth
from starlette.responses import JSONResponse
from starlette.websockets import WebSocketDisconnect

from models.m import IDCardInfo, User, UserNotification
from schemas.indiv_schemas import OcrRequest
from utils.myredis import myRedis
from utils.webSocket import wbs


access_key = 'oDQ7AXY0k0PMqe6HZxaZcadWa_7hWYCIwsbgTAPt'
secret_key = 'XDlivC-mJTlFOzNWwKNXY9exMplXv8M3szzSLsRR'
bucket_name = 'molviu'
token_expires = 3600  # 过期时间（秒）


indiv_router = APIRouter(prefix="/indiv", tags=["个人信息"])


@indiv_router.get("/get_token", summary="获取七牛云上传Token")
async def get_qiniu_token(request: Request):
    # 获取七牛云上传 Token（需要登录）
    # 从中间件存储的 request.state 中获取用户信息
    current_user = request.state.user

    q = Auth(access_key, secret_key)
    token = q.upload_token(bucket_name, expires=token_expires)
    return JSONResponse(
        content={
            "code": 1000,
            "data": token,
            "user_id": current_user.get("sub"),  # 从中间件验证的用户信息中获取
            "username": current_user.get("username")
        },
        status_code=200
    )


@indiv_router.post("/baiduAPICard", summary="身份证OCR识别")
async def baiDuAPICard(request: Request, ocr_data: OcrRequest):
    # 从中间件获取当前登录用户
    current_user = request.state.user
    user_id = current_user.get("sub")

    # 存储 user_id 和 picurl 到 Redis（JSON 格式）
    myRedis.rpush("id_card", json.dumps({
        "user_id": user_id,
        "picurl": ocr_data.picurl
    }))

    user = await User.get_or_none(id=user_id)
    if not user:
        return JSONResponse({"code": 400, "data": "用户不存在"})
    user.is_real = 2
    await user.save()
    return JSONResponse({"code": 200, "data": "审核中，请等待1-3个工作日"})


@indiv_router.get("/check_idcard_auth", summary="查询用户实名认证状态")
async def check_idcard_auth(user_id: int):
    if not user_id:
        return JSONResponse({"code": 200, "msg": "用户id不能为空"})
    user = await User.get_or_none(id=user_id)
    if not user:
        return JSONResponse({"code": 200, "msg": "用户不存在"})

    # 根据 is_real 状态返回不同的信息
    if user.is_real == 0:
        return JSONResponse({
            "code": 200,
            "msg": "用户未认证",
            "data": {"is_real": user.is_real}
        })
    elif user.is_real == 2:
        return JSONResponse({
            "code": 200,
            "msg": "用户待审核",
            "data": {
                "is_real": user.is_real,
                "message": "您的实名认证正在审核中，请耐心等待1-3个工作日"
            }
        })
    elif user.is_real == 1:
        # 已认证 - 查询身份证信息
        idcard_info = await IDCardInfo.get_or_none(user_id=user_id)
        if idcard_info:
            return JSONResponse({
                "code": 200,
                "msg": "用户已认证",
                "data": {
                    "is_real": user.is_real,
                    "name": idcard_info.name,
                    "idcard_number": idcard_info.idcard_number
                }
            })
        else:
            return JSONResponse({
                "code": 200,
                "msg": "用户已认证但无身份证信息",
                "data": {"is_real": user.is_real}
            })

    # 其他未知状态
    return JSONResponse({
        "code": 400,
        "msg": "未知的认证状态",
        "data": {"is_real": user.is_real}
    })


@indiv_router.websocket("/ws/{client_id}")
async def websocket_endpoint(websocket: WebSocket, client_id: str):
    await wbs.connect(websocket, client_id)
    try:
        while True:
            # 保持连接活跃，但不阻塞事件循环
            await asyncio.sleep(0)
    except WebSocketDisconnect:
        wbs.disconnect(websocket, client_id)


@indiv_router.get("/push/")
async def push_to_client(client_id: str, message: str):
    """
    手动推送消息到指定客户端（测试用）
    message 需要是 JSON 字符串格式，例如：
    {"type":"success","title":"测试通知","content":"这是一条测试消息"}
    """
    try:
        # 尝试解析 message 为 JSON 对象
        import json
        message_obj = json.loads(message)
        await wbs.send_to_client(client_id, message_obj)
    except json.JSONDecodeError:
        # 如果不是 JSON，则作为普通字符串发送
        await wbs.send_to_client(client_id, {"type": "system", "title": "系统消息", "content": message})
    
    return {"status": "success", "message": f"已向客户端 {client_id} 推送消息"}


@indiv_router.get("/notifications/unread", summary="获取用户未读通知列表")
async def get_unread_notifications(request: Request):
    """
    获取用户所有未读通知
    - 用户在 WebSocket 连接期间如果有消息，则实时推送
    - 如果用户离线，消息会保存到数据库
    - 用户登录/连接时，可以通过此接口获取离线期间的所有消息
    """
    current_user = request.state.user
    user_id = current_user.get("sub")

    # 获取所有未读消息
    notifications = await UserNotification.filter(user_id=user_id).all()

    if not notifications:
        return JSONResponse({
            "code": 200,
            "data": [],
            "message": "暂无未读消息"
        })

    # 将消息内容提取出来
    messages = [notification.message for notification in notifications]

    return JSONResponse({
        "code": 200,
        "data": messages,
        "count": len(messages),
        "message": "成功获取未读消息"
    })


@indiv_router.delete(
    "/notifications/unread/{notification_id}",
    summary="清除指定通知"
)
async def delete_notification(request: Request, notification_id: int):
    """删除指定的通知"""
    current_user = request.state.user
    user_id = current_user.get("sub")

    notification = await UserNotification.get_or_none(
        id=notification_id, user_id=user_id
    )
    if not notification:
        return JSONResponse({
            "code": 404,
            "message": "通知不存在"
        })

    await notification.delete()
    return JSONResponse({
        "code": 200,
        "message": "通知已删除"
    })


@indiv_router.delete(
    "/notifications/clear-all",
    summary="清除所有未读通知"
)
async def clear_all_notifications(request: Request):
    """一键清除用户的所有未读通知"""
    current_user = request.state.user
    user_id = current_user.get("sub")

    count = await UserNotification.filter(user_id=user_id).delete()
    return JSONResponse({
        "code": 200,
        "data": {"deleted_count": count},
        "message": f"已清除 {count} 条未读消息"
    })
